home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / utility / uwserver.zip / uwserver.tar / misc / macmouse.el < prev    next >
Lisp/Scheme  |  1991-01-25  |  9KB  |  272 lines

  1. ;;;  macmouse.el (Version: 2.0)
  2.  
  3. ;;;  Copyright (C) Gregory S. Lauer (glauer@bbn), 1985. 
  4. ;;;    Please send suggestions and corrections to the above address.
  5. ;;;
  6. ;;;  This file contains macmouse, a GNU Emacs mouse package for UW.
  7.  
  8.  
  9. ;;
  10. ;; GNU Emacs is distributed in the hope that it will be useful,
  11. ;; but without any warranty.  No author or distributor
  12. ;; accepts responsibility to anyone for the consequences of using it
  13. ;; or for whether it serves any particular purpose or works at all,
  14. ;; unless he says so in writing.
  15.  
  16. ;; Everyone is granted permission to copy, modify and redistribute
  17. ;; GNU Emacs, but only under the conditions described in the
  18. ;; document "GNU Emacs copying permission notice".   An exact copy
  19. ;; of the document is supposed to have been given to you along with
  20. ;; GNU Emacs so that you can know how you may redistribute it all.
  21. ;; It should be in a file named COPYING.  Among other things, the
  22. ;; copyright notice and this notice must be preserved on all copies.
  23.  
  24.  
  25. ;;;  Original version for Gosling emacs by Chris Kent, Purdue University 1985.
  26. ;;;  Modified by Gregory Lauer, BBN, Novemeber 1985.
  27. ;
  28. ;
  29. ;
  30. ; Macmouse provides the following features:
  31. ;  Up or down mouse button in a window selects that window
  32. ;
  33. ;  A scroll bar/thumbing area for each window with the following features:
  34. ;       the mode lines are horizontal scroll bars
  35. ;           (running from rightmost column to under leftmost column)
  36. ;       the unused right window bar and the dividing lines between
  37. ;           windows are vertical scroll bars
  38. ;           (running from top of window THRU modeline
  39. ;   for vertical scroll bars:
  40. ;     click at line 1 does previous page
  41. ;    click at last line does next page
  42. ;     click anywhere else "thumbs" to the relative portion of the buffer.
  43. ;     shift-click at line 1 scrolls one line down
  44. ;     shift-click at last line scrolls one line up
  45. ;     shift-click elsewhere moves line to top of window
  46. ;     option-shift-click elsewhere moves line to bottom of window
  47. ;   for horizontal scroll bars:
  48. ;       click at column 1 does scroll right one window width
  49. ;       click at last column does scroll left one window width
  50. ;       click anywhere else moves to that "percent" of the buffer width
  51. ;       shift-click at column 1 scrolls one column right
  52. ;       shift-click at last column scrolls one column left
  53. ;       shift-click elsewhere moves column to right of window
  54. ;       option-shift-click elsewhere moves column to left of window
  55. ;
  56. ; There is also basic positioning and kill-buffer support:
  57. ;     click in a buffer moves dot there and selects that buffer
  58. ;     drag copies the dragged region to the kill buffer
  59. ;     shift-drag deletes the dragged region to the kill buffer
  60. ;
  61. ;   It is possible to use the scrolling and thumbing area to make the region
  62. ;   larger than a single screen; just click, scroll, release. Make sure
  63. ;   that the last scroll is just a down event; the up must be in the buffer.
  64. ;   The last mouse position is remembered for each different buffer (not
  65. ;   window), and thus you can start a drag in one buffer, select another,
  66. ;   go back to the first buffer, etc.
  67. ;
  68. ;     option-click yanks from the kill buffer
  69. ;     option-shift-click similarly yanks from a named buffer.
  70.  
  71. (defconst mouse-max-x 95 "Maximum UW column returned on mouse click")
  72. (defconst mouse-max-y 95 "Maximum UW row returned on mouse click")
  73.  
  74. (make-variable-buffer-local 'mouse-last-x) ; x of last event
  75. (set-default 'mouse-last-x 0)
  76.  
  77. (make-variable-buffer-local 'mouse-last-y) ; y of last event
  78. (set-default 'mouse-last-y 0)
  79.  
  80. (make-variable-buffer-local 'mouse-last-b) ; buttons at last event
  81. (set-default 'mouse-last-b 0)
  82.  
  83. (make-variable-buffer-local 'mouse-last-dot) ; dot after last event
  84. (set-default 'mouse-last-dot 0)
  85.  
  86. (make-variable-buffer-local 'scrolling-p)
  87. (set-default 'scrolling-p nil)
  88.  
  89. (defun move-mac-cursor ()
  90.   (interactive)
  91.   (let (savest b x y up down lock shift option command)
  92.     (setq savest stack-trace-on-error)
  93.     (setq stack-trace-on-error nil)
  94.                     ; decode everything
  95.     (setq y (- (read-char) 32))
  96.     (setq x (- (read-char) 32))
  97.     (setq b (- (read-char) 32))
  98.     (setq command (< 0 (logand b 1)))    ; command key
  99.     (setq shift (< 0 (logand b 2)))    ; shift
  100.     (setq lock (< 0 (logand b 4)))    ; caps-lock
  101.     (setq option (< 0 (logand b 8)))    ; option
  102.     (setq down (< 0 (logand b 16)))    ; mouse down
  103.     (setq up (< 0 (logand b 32)))    ; mouse up
  104.     (condition-case ()
  105.     (progn
  106.       (select-window-containing-x-and-y x y) ; side-effect sets scrolling-p
  107.       (if scrolling-p
  108.           (mouse-scroll-region b x y)
  109.         (progn
  110.           (move-to-window-x-y x y)    ; move cursor to mouse-dot always
  111.           (if down (setq mouse-last-dot (dot)))
  112.           (mouse-edit-action))))
  113.       (error (message "Click not in selectable window")
  114.          (sit-for 1)
  115.          (message "")))
  116.     (setq stack-trace-on-error savest)
  117.     (if down
  118.     (progn 
  119.       (setq mouse-last-x x)
  120.       (setq mouse-last-y y)
  121.       (setq mouse-last-b b))
  122.       (progn 
  123.     (setq mouse-last-x 0)
  124.     (setq mouse-last-y 0)
  125.     (setq mouse-last-b 0)))))
  126.  
  127. (defun mouse-edit-action ()
  128.                                 ;marking and editing actions on buttons:
  129.                 ;   if no movement, nothing.
  130.                 ;   if movement, save mouse-last-dot,
  131.                 ;      and edit.
  132.                 ; editing (on upstrokes):
  133.                 ;   unmodified, copy to kill buffer.
  134.                 ;   SHIFTed, delete (cut) to kill buffer.
  135.                 ; 
  136.                 ; option-click yanks from kill buffer; 
  137.                 ; shift-option-click from named buffer.
  138.   (let ((fun (get 'mouse-function b)))
  139.     (if fun (apply fun nil))))
  140.  
  141.  
  142.     ; individual button bindings
  143.     ; generally will only need up mouse button: mouse-last-dot
  144.     ; is saved automatically on down mouse button
  145.  
  146. ; only need to define functions for keys that get used
  147.  
  148. (put 'mouse-function 32            ; up
  149.      '(lambda ()
  150.          (if (and (not (mouse-click-p))
  151.          (not scrolling-p))
  152.         (copy-region-as-kill (dot) mouse-last-dot))))
  153.  
  154. (put 'mouse-function 34            ; up/shift
  155.      '(lambda ()
  156.          (if (and (not (mouse-click-p))
  157.          (not scrolling-p))
  158.            (kill-region (dot) mouse-last-dot))))
  159.  
  160. (put 'mouse-function 40            ; up/option
  161.      '(lambda ()
  162.          (if (mouse-click-p)
  163.         (progn
  164.           (yank)
  165.           (exchange-dot-and-mark)))))
  166.  
  167. (put 'mouse-function 42
  168.      '(lambda ()        ; up/option/shift
  169.     (if (mouse-click-p)
  170.         (insert-buffer (read-buffer "Insert contents of buffer: ")))))
  171.  
  172. (defun mouse-click-p ()
  173.   (= (dot) mouse-last-dot))
  174.  
  175. (defun set-window-boundaries ()
  176.   (let ((edges (window-edges)))
  177.     (setq xl (1+ (car edges)))
  178.     (setq yt (1+ (car (cdr edges))))
  179.     (let ((temp (car (cdr (cdr edges)))))
  180.       (setq xr (if (= (screen-width) temp) mouse-max-x temp)))
  181.     (let ((temp (car (cdr (cdr (cdr edges))))))
  182.       (setq yb (if (= (screen-height) temp) mouse-max-y temp )))))
  183.  
  184. (defun select-window-containing-x-and-y (x y)
  185.   (let ((starting-window (selected-window)))
  186.     (set-window-boundaries)
  187.     (while (not (point-in-window x y))
  188.       (other-window 1)
  189.       (if (eq (selected-window) starting-window)
  190.       (error nil)
  191.     (set-window-boundaries)))
  192.     (if (or (= x xr) (= y yb))
  193.     (setq scrolling-p t)
  194.       (setq scrolling-p nil))))
  195.  
  196. (defun point-in-window (x y)
  197.   (and (<= xl x)(<= x xr)(<= yt y)(<= y yb)))
  198.  
  199. (defun move-to-window-x-y (x y)
  200.   (move-to-window-line (- y yt))
  201.   (move-to-window-column (- x xl)))
  202.  
  203. (defun move-to-window-column (x)
  204.   (move-to-column (+ (max 0 (- (window-hscroll) 1)) x)))
  205.  
  206. (defun mouse-scroll-region (b x y)
  207.   (if down
  208.       (if shift
  209.       (do-lines b x y)
  210.     (do-pages b x y)))
  211.   (if (and up
  212.        (or (/= x mouse-last-x)
  213.            (/= y mouse-last-y)))
  214.       (if shift
  215.       (do-lines b x y)
  216.     (do-pages b x y))))
  217.  
  218. (defun do-lines (b x y)            ; fine control over lines
  219.   (if (= x xr)
  220.       (cond ((= y yt)(scroll-down 1))
  221.         ((= y yb)(scroll-up 1))
  222.         (t (if option
  223.            (scroll-down (- yb y 1))
  224.          (scroll-up (- y yt))))))
  225.   (if (and (= y yb) (/= x xr))
  226.       (cond ((<= x xl)(scroll-right 1))
  227.         ((>= x (1- xr))(scroll-left 1))
  228.         (t (if option
  229.            (move-column-right x)
  230.          (move-column-left x))))))
  231.  
  232. (defun move-column-left (x)        ;need to mess about a bit because
  233.   (scroll-left                ;first scroll left of 1 just writes
  234.    (if (= (window-hscroll) 0)        ;a column of $s in column 1
  235.        (- x xl)
  236.      (- x xl 1))))
  237.  
  238. (defun move-column-right (x)
  239.   (scroll-right (- xr x 2)))
  240.  
  241.  
  242. (defun do-pages (b x y)            ; large motions via pages and thumbing
  243.   (if (= x xr)
  244.       (cond ((= y yt)(scroll-down nil))
  245.         ((= y yb)(scroll-up nil))
  246.         (t (goto-percent (/ (* (- y yt 1) 100)
  247.                 (- yb yt 2))))))
  248.   (if (and (= y yb)(/= x xr))
  249.       (cond ((<= x xl)(scroll-right (- (window-width)
  250.                        next-screen-context-lines)))
  251.         ((>= x (1- xr))(scroll-left (- (window-width)
  252.                        next-screen-context-lines)))
  253.         (t (goto-horizontal-percent (/ (* (- x xl 1) 100)
  254.                        (- xr xl 2)))))))
  255.  
  256. (defun goto-percent (p)
  257.   (goto-char (/ (* (- (dot-max) (dot-min)) p) 100)))
  258.  
  259. (defun goto-horizontal-percent (p)    ;try to put this percent of columns
  260.   (let ((window-offset (window-hscroll));in the center column of the window
  261.     delta)                ;unless that would move the first or
  262.     (setq delta                ;last column past the window edge
  263.       (- window-offset
  264.          (min (max 0 (- (/ (* (screen-width) p) 100)
  265.                 (/ (- xr xl) 2)))
  266.           (- (screen-width) (- xr xl)))))
  267.     (scroll-right delta)))
  268.  
  269.     
  270. (global-set-key "\em" 'move-mac-cursor)
  271.